#include <iostream>
#include <string>
#include <mysql/mysql.h>

static const std::string host = "127.0.0.1";
static const std::string user = "qingdiaoshen";
static const std::string password = "2248079321qCl-+.";
static const std::string database = "scott";
static unsigned int port = 3306;

void execute_query(MYSQL* mysql_handle,const std::string query)
{
    int code = mysql_query(mysql_handle,query.c_str());
    if (code != 0)
    {
        std::cout << "execute:" << query << " failed" << std::endl;
        exit(-1); 
    }

    std::cout << "execute:" << query << " success" << std::endl;
}

int main()
{
    //获取mysql客户端版本
    //std::cout << "client version: " << mysql_get_client_info() << std::endl; 
    //1.创建mysql句柄
    MYSQL* mysql_handle = mysql_init(nullptr);

    //2.连接数据库
    if (mysql_real_connect(mysql_handle, host.c_str(), user.c_str(),
        password.c_str(), database.c_str(), 3306,nullptr, 0) == nullptr)
    {
        std::cout << "connect failed" << std::endl;
        return 1;
    }

	std::cout << "connect success" << std::endl;

    //如果出现乱码的话,可以设置连接的编码格式,这里默认是utf8,有的默认是拉丁
    mysql_set_character_set(mysql_handle, "utf8");

    //3.创建数据库
    std::string sql = "create table if not exists test(id int,name varchar(20))";
    execute_query(mysql_handle, sql);

    //4.访问数据库
    //std::string sql1 = "insert into test values (2,'liukun233')";
    //std::string sql1 = "update test set name='kunkun' where id=2";
    //std::string sql1 = "delete from test where id=2";
    //execute_query(mysql_handle, sql1);
    
    //上面三个是最简单的,只需要sql执行完成了,就可以了
    //select其实是最不好出处理的,因为你需要自己设置查看数据的格式
    //4.1 sql执行完毕只是第一步,还需要对数据进行进一步的解析
    std::string sql1 = "select * from emp";
    execute_query(mysql_handle, sql1);

    //4.2 获取select查询结果的行号和列号
    //这里的函数调用是使用了malloc的,所以记得释放
    MYSQL_RES* res = mysql_store_result(mysql_handle);
    int rows = mysql_num_rows(res);
    int cols = mysql_num_fields(res);
    std::cout << "select的查询结果中行数有" << rows << "列数有" << cols << std::endl;

    //4.3 获取表中的各个字段,这个步骤我们一般不会使用,仅仅是为了测试代码的完整性
    MYSQL_FIELD* fields = mysql_fetch_fields(res);
    for (int i = 0; i < cols; ++i)
    {
        std::cout << fields[i].name << "\t\t";
    }
    std::cout << std::endl;

    //4.4 获取表中的数据
    for (int i = 0; i < rows; ++i)
    {
        
        MYSQL_ROW line = mysql_fetch_row(res);
        for(int j = 0; j < cols; j++)
        {
            if (line[j] != nullptr)
            {
                std::cout << line[j] << "\t\t"; //将记录内部的多列字符串依次打印！
            }
            else
            {
                std::cout << "NULL" << "\t\t";
            }
        }
        std::cout << std::endl;
    }
    
    //5.关闭数据库,释放有关资源
    //free(res);
    //free(fields);
    mysql_close(mysql_handle);
    return 0;
}
